import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'dart:math' as Math;

class SliverListPage extends StatefulWidget {
  @override
  _SliverListPageState createState() => _SliverListPageState();
}

class _SliverListPageState extends State<SliverListPage>
    with SingleTickerProviderStateMixin {
  int listCount = 30;
  List<Widget> _sliverBuilder(BuildContext context, bool innerBoxIsScrolled) {
    return <Widget>[
      // 头部信息
      SliverPersistentHeader(
        delegate: DGSliverHeaderDelegate(
          maxHeight: 60,
          minHeight: 60,
          changeSize: true,
          snapConfig: FloatingHeaderSnapConfiguration(
            vsync: this,
            curve: Curves.bounceInOut,
            duration: const Duration(milliseconds: 10),
          ),
          builder: (
            BuildContext context,
            double shrinkOffset,
            bool overlapsContent,
          ) {
            ///根据数值计算偏差
            var lr = 10 - shrinkOffset / 60 * 10;
            return SizedBox.expand(
              child: Padding(
                padding:
                    EdgeInsets.only(bottom: 10, left: lr, right: lr, top: lr),
                child: Row(
                  mainAxisSize: MainAxisSize.max,
                  children: <Widget>[
                    Expanded(
                      child: Container(
                        alignment: Alignment.center,
                        color: Colors.orangeAccent,
                        child: FlatButton(
                          onPressed: () {
                            setState(() {
                              listCount = 30;
                            });
                          },
                          child: Text('按键1'),
                        ),
                      ),
                    ),
                    Expanded(
                      child: Container(
                        alignment: Alignment.center,
                        color: Colors.orangeAccent,
                        child: FlatButton(
                          onPressed: () {
                            setState(() {
                              listCount = 4;
                            });
                          },
                          child: Text('按键2'),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('sliver list page'),
      ),
      body: Container(
        child: NestedScrollView(
          physics: const AlwaysScrollableScrollPhysics(),
          headerSliverBuilder: _sliverBuilder,
          body: ListView.builder(
            itemBuilder: (_, index) {
              return Card(
                child: Container(
                  height: 60,
                  padding: EdgeInsets.only(left: 10),
                  alignment: Alignment.centerLeft,
                  child: Text('Item $index'),
                ),
              );
            },
            // 根据状态返回数量
            itemCount: listCount,
          ),
        ),
      ),
    );
  }
}

// 动态头部处理
class DGSliverHeaderDelegate extends SliverPersistentHeaderDelegate {
  final double minHeight;
  final double maxHeight;
  final Widget child;
  final Builder builder;
  final bool changeSize;
  final FloatingHeaderSnapConfiguration snapConfig;
  AnimationController animationController;

  DGSliverHeaderDelegate({
    @required this.minHeight,
    @required this.maxHeight,
    @required this.snapConfig,
    this.child,
    this.builder,
    this.changeSize = false,
  });

  @override
  double get minExtent => minHeight;

  @override
  double get maxExtent => Math.max(maxHeight, minHeight);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    if (builder != null) {
      return builder(context, shrinkOffset, overlapsContent);
    }
    return child;
  }

  @override
  bool shouldRebuild(DGSliverHeaderDelegate oldDelegate) {
    return true;
  }

  @override
  FloatingHeaderSnapConfiguration get snapConfiguration => snapConfig;
}

typedef Widget Builder(
  BuildContext context,
  double shrinkOffset,
  bool overlapsContent,
);
